/**
 * 缓存管理器
 * 提供本地存储、内存缓存、过期策略等功能
 */
class CacheManager {
    constructor(options = {}) {
        this.storage = options.storage || 'localStorage'; // 'localStorage', 'sessionStorage', 'memory'
        this.defaultTTL = options.defaultTTL || 300000; // 5分钟
        this.prefix = options.prefix || 'app_cache_';
        this.compression = options.compression || false;
        this.debug = options.debug || false;

        // 内存缓存
        this.memoryCache = new Map();

        // 统计信息
        this.stats = {
            hits: 0,
            misses: 0,
            sets: 0,
            deletes: 0,
            clears: 0
        };

        // 初始化存储
        this.initStorage();
    }

    /**
     * 初始化存储
     */
    initStorage() {
        try {
            if (this.storage === 'localStorage') {
                this.storageInstance = localStorage;
            } else if (this.storage === 'sessionStorage') {
                this.storageInstance = sessionStorage;
            } else {
                this.storageInstance = null;
            }

            // 清理过期的缓存项
            this.cleanupExpired();
        } catch (error) {
            console.error('[CacheManager] Storage initialization failed:', error);
            this.storageInstance = null;
        }
    }

    /**
     * 生成缓存键
     */
    generateKey(key) {
        return `${this.prefix}${key}`;
    }

    /**
     * 序列化数据
     */
    serialize(data) {
        return JSON.stringify({
            data,
            timestamp: Date.now(),
            version: 1
        });
    }

    /**
     * 反序列化数据
     */
    deserialize(serialized) {
        try {
            const parsed = JSON.parse(serialized);
            return parsed;
        } catch (error) {
            console.error('[CacheManager] Deserialization failed:', error);
            return null;
        }
    }

    /**
     * 检查是否过期
     */
    isExpired(item, ttl) {
        if (!item.timestamp) return true;
        return Date.now() - item.timestamp > ttl;
    }

    /**
     * 设置缓存
     */
    async set(key, value, ttl = this.defaultTTL) {
        try {
            const cacheKey = this.generateKey(key);
            const serialized = this.serialize(value);

            if (this.storageInstance) {
                this.storageInstance.setItem(cacheKey, serialized);

                // 设置过期时间（使用单独的键）
                if (ttl !== Infinity) {
                    const expiryKey = `${cacheKey}_expiry`;
                    this.storageInstance.setItem(expiryKey, Date.now() + ttl);
                }
            } else {
                // 内存缓存
                this.memoryCache.set(cacheKey, {
                    data: serialized,
                    expiry: ttl === Infinity ? null : Date.now() + ttl
                });
            }

            this.stats.sets++;

            if (this.debug) {
                console.log(`[CacheManager] Set: ${key}, TTL: ${ttl}ms`);
            }

            return true;
        } catch (error) {
            console.error('[CacheManager] Set failed:', error);
            return false;
        }
    }

    /**
     * 获取缓存
     */
    async get(key, defaultValue = null) {
        try {
            const cacheKey = this.generateKey(key);
            let serialized = null;
            let expiryTime = null;

            if (this.storageInstance) {
                serialized = this.storageInstance.getItem(cacheKey);
                const expiryKey = `${cacheKey}_expiry`;
                const expiryValue = this.storageInstance.getItem(expiryKey);
                expiryTime = expiryValue ? parseInt(expiryValue) : null;
            } else {
                // 内存缓存
                const cached = this.memoryCache.get(cacheKey);
                if (cached) {
                    serialized = cached.data;
                    expiryTime = cached.expiry;
                }
            }

            if (!serialized) {
                this.stats.misses++;
                return defaultValue;
            }

            // 检查过期
            if (expiryTime && Date.now() > expiryTime) {
                await this.delete(key);
                this.stats.misses++;
                return defaultValue;
            }

            const item = this.deserialize(serialized);
            if (!item) {
                this.stats.misses++;
                return defaultValue;
            }

            this.stats.hits++;

            if (this.debug) {
                console.log(`[CacheManager] Hit: ${key}`);
            }

            return item.data;
        } catch (error) {
            console.error('[CacheManager] Get failed:', error);
            this.stats.misses++;
            return defaultValue;
        }
    }

    /**
     * 删除缓存
     */
    async delete(key) {
        try {
            const cacheKey = this.generateKey(key);

            if (this.storageInstance) {
                this.storageInstance.removeItem(cacheKey);
                const expiryKey = `${cacheKey}_expiry`;
                this.storageInstance.removeItem(expiryKey);
            } else {
                this.memoryCache.delete(cacheKey);
            }

            this.stats.deletes++;

            if (this.debug) {
                console.log(`[CacheManager] Delete: ${key}`);
            }

            return true;
        } catch (error) {
            console.error('[CacheManager] Delete failed:', error);
            return false;
        }
    }

    /**
     * 检查是否存在
     */
    async has(key) {
        try {
            const cacheKey = this.generateKey(key);

            if (this.storageInstance) {
                const serialized = this.storageInstance.getItem(cacheKey);
                if (!serialized) return false;

                const expiryKey = `${cacheKey}_expiry`;
                const expiryValue = this.storageInstance.getItem(expiryKey);

                if (expiryValue && Date.now() > parseInt(expiryValue)) {
                    await this.delete(key);
                    return false;
                }

                return true;
            } else {
                const cached = this.memoryCache.get(cacheKey);
                if (!cached) return false;

                if (cached.expiry && Date.now() > cached.expiry) {
                    this.memoryCache.delete(cacheKey);
                    return false;
                }

                return true;
            }
        } catch (error) {
            console.error('[CacheManager] Has check failed:', error);
            return false;
        }
    }

    /**
     * 清除缓存
     */
    async clear(pattern = null) {
        try {
            if (pattern) {
                // 清除匹配模式的键
                await this.clearByPattern(pattern);
            } else {
                // 清除所有缓存
                if (this.storageInstance) {
                    const keys = Object.keys(this.storageInstance);
                    const prefixRegex = new RegExp(`^${this.prefix}`);

                    for (const key of keys) {
                        if (prefixRegex.test(key)) {
                            this.storageInstance.removeItem(key);
                        }
                    }
                } else {
                    this.memoryCache.clear();
                }
            }

            this.stats.clears++;

            if (this.debug) {
                console.log(`[CacheManager] Clear: ${pattern || 'all'}`);
            }

            return true;
        } catch (error) {
            console.error('[CacheManager] Clear failed:', error);
            return false;
        }
    }

    /**
     * 按模式清除缓存
     */
    async clearByPattern(pattern) {
        const regex = new RegExp(pattern);

        if (this.storageInstance) {
            const keys = Object.keys(this.storageInstance);
            const prefixRegex = new RegExp(`^${this.prefix}`);

            for (const key of keys) {
                if (prefixRegex.test(key)) {
                    const actualKey = key.substring(this.prefix.length);
                    if (regex.test(actualKey)) {
                        this.storageInstance.removeItem(key);
                        const expiryKey = `${key}_expiry`;
                        this.storageInstance.removeItem(expiryKey);
                    }
                }
            }
        } else {
            const keysToDelete = [];
            for (const [key] of this.memoryCache) {
                if (key.startsWith(this.prefix)) {
                    const actualKey = key.substring(this.prefix.length);
                    if (regex.test(actualKey)) {
                        keysToDelete.push(key);
                    }
                }
            }

            for (const key of keysToDelete) {
                this.memoryCache.delete(key);
            }
        }
    }

    /**
     * 清理过期缓存
     */
    async cleanupExpired() {
        try {
            const now = Date.now();

            if (this.storageInstance) {
                const keys = Object.keys(this.storageInstance);
                const prefixRegex = new RegExp(`^${this.prefix}`);

                for (const key of keys) {
                    if (prefixRegex.test(key) && key.endsWith('_expiry')) {
                        const expiryTime = parseInt(this.storageInstance.getItem(key));
                        if (expiryTime && now > expiryTime) {
                            const dataKey = key.substring(0, key.length - 7); // 移除'_expiry'
                            this.storageInstance.removeItem(dataKey);
                            this.storageInstance.removeItem(key);
                        }
                    }
                }
            } else {
                const keysToDelete = [];
                for (const [key, value] of this.memoryCache) {
                    if (value.expiry && now > value.expiry) {
                        keysToDelete.push(key);
                    }
                }

                for (const key of keysToDelete) {
                    this.memoryCache.delete(key);
                }
            }

            if (this.debug) {
                console.log('[CacheManager] Cleanup completed');
            }
        } catch (error) {
            console.error('[CacheManager] Cleanup failed:', error);
        }
    }

    /**
     * 获取所有键
     */
    async keys() {
        const result = [];

        if (this.storageInstance) {
            const keys = Object.keys(this.storageInstance);
            const prefixRegex = new RegExp(`^${this.prefix}`);

            for (const key of keys) {
                if (prefixRegex.test(key) && !key.endsWith('_expiry')) {
                    result.push(key.substring(this.prefix.length));
                }
            }
        } else {
            for (const key of this.memoryCache.keys()) {
                if (key.startsWith(this.prefix)) {
                    result.push(key.substring(this.prefix.length));
                }
            }
        }

        return result;
    }

    /**
     * 获取缓存大小
     */
    async size() {
        if (this.storageInstance) {
            const keys = Object.keys(this.storageInstance);
            const prefixRegex = new RegExp(`^${this.prefix}`);
            let count = 0;

            for (const key of keys) {
                if (prefixRegex.test(key) && !key.endsWith('_expiry')) {
                    count++;
                }
            }

            return count;
        } else {
            let count = 0;
            for (const key of this.memoryCache.keys()) {
                if (key.startsWith(this.prefix)) {
                    count++;
                }
            }
            return count;
        }
    }

    /**
     * 获取统计信息
     */
    getStats() {
        const total = this.stats.hits + this.stats.misses;
        const hitRate = total > 0 ? (this.stats.hits / total * 100).toFixed(2) : 0;

        return {
            ...this.stats,
            total,
            hitRate: `${hitRate}%`,
            size: this.memoryCache.size
        };
    }

    /**
     * 重置统计信息
     */
    resetStats() {
        this.stats = {
            hits: 0,
            misses: 0,
            sets: 0,
            deletes: 0,
            clears: 0
        };
    }

    /**
     * 设置压缩选项
     */
    setCompression(enabled) {
        this.compression = enabled;
    }

    /**
     * 设置前缀
     */
    setPrefix(prefix) {
        this.prefix = prefix;
    }

    /**
     * 设置默认TTL
     */
    setDefaultTTL(ttl) {
        this.defaultTTL = ttl;
    }

    /**
     * 批量操作
     */
    async mget(keys) {
        const results = {};
        for (const key of keys) {
            results[key] = await this.get(key);
        }
        return results;
    }

    async mset(items, ttl = this.defaultTTL) {
        const results = {};
        for (const [key, value] of Object.entries(items)) {
            results[key] = await this.set(key, value, ttl);
        }
        return results;
    }

    async mdelete(keys) {
        const results = {};
        for (const key of keys) {
            results[key] = await this.delete(key);
        }
        return results;
    }
}

// 导出CacheManager
window.CacheManager = CacheManager;